﻿using IdentityServer4.EntityFramework.DbContexts;
using IdentityServer4.EntityFramework.Interfaces;
using IdentityServer4.EntityFramework.Mappers;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using SX.AuthServer.Models;
using SX.Core;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace SX.AuthServer.Seed
{
    /// <summary>
    /// 生成初始化数据
    /// </summary>
    public class EnsureSeedData
    {
        private UserManager<ApplicationUser> _userManager;
        private RoleManager<ApplicationRole> _roleManager;
        private ILogger _logger;
        private AppSettings _appSettings;

        public async Task EnsureSeedDataAsync(IServiceProvider services)
        {
            using (var scope = services.GetRequiredService<IServiceScopeFactory>().CreateScope())
            {
                _logger = scope.ServiceProvider.GetRequiredService<ILogger<EnsureSeedData>>();
                _userManager = scope.ServiceProvider.GetRequiredService<UserManager<ApplicationUser>>();
                _roleManager = scope.ServiceProvider.GetRequiredService<RoleManager<ApplicationRole>>();
                _appSettings= scope.ServiceProvider.GetRequiredService<AppSettings>();
                await EnsureIdentitySeedAsync();
                await EnsureIdentityServerSeedAsync(scope.ServiceProvider);
            }

        }
        private async Task EnsureIdentitySeedAsync()
        {
            if (!await _roleManager.RoleExistsAsync("系统管理员"))
            {
                var role = new ApplicationRole() { Name = "系统管理员", NormalizedName = "系统管理员" , Id = GuidHelper.NewSequentialGuid() };
                var result = await _roleManager.CreateAsync(role);
                if (!result.Succeeded)
                {
                    throw new Exception("初始化默认角色失败:" + result.Errors.SelectMany(e => e.Description));
                }
            }
            if (await _userManager.FindByNameAsync("admin") == null)
            {
                var defaultUser = new ApplicationUser
                {
                    Id=GuidHelper.NewSequentialGuid(),
                    UserName ="admin",
                    SecurityStamp = "admin",
                    Password= Md5Encrypt.Encrypt32("123456")
                };
                var result = await _userManager.CreateAsync(defaultUser);
                if (!result.Succeeded)
                {
                    throw new Exception("初始默认用户失败");
                }
                await _userManager.AddToRoleAsync(defaultUser,"系统管理员");
            }
            _logger.LogInformation("初始化identity信息成功");
        }
        private async Task EnsureIdentityServerSeedAsync(IServiceProvider services)
        {
            IConfigurationDbContext configurationDbContext = null;
            services.GetRequiredService<PersistedGrantDbContext>().Database.Migrate();
            configurationDbContext = services.GetRequiredService<ConfigurationDbContext>();

            if (!configurationDbContext.Clients.Any())
            {
                foreach (var client in Config.GetClients(_appSettings))
                {
                    await configurationDbContext.Clients.AddAsync(client.ToEntity());
                }
                await ((DbContext)configurationDbContext).SaveChangesAsync();
            }

            if (!configurationDbContext.ApiResources.Any())
            {
                foreach (var api in Config.ApiResources)
                {
                    await configurationDbContext.ApiResources.AddAsync(api.ToEntity());
                }
                await ((DbContext)configurationDbContext).SaveChangesAsync();
            }

            if (!configurationDbContext.ApiScopes.Any())
            {
                foreach (var api in Config.ApiScopes)
                {
                    await configurationDbContext.ApiScopes.AddAsync(api.ToEntity());
                }
                await ((DbContext)configurationDbContext).SaveChangesAsync();
            }

            if (!configurationDbContext.IdentityResources.Any())
            {
                foreach (var identity in Config.IdentityResources)
                {
                    await configurationDbContext.IdentityResources.AddAsync(identity.ToEntity());
                }
                await ((DbContext)configurationDbContext).SaveChangesAsync();
            }
            _logger.LogInformation("初始化identityserver信息成功");
        }
    }
}
